grammar Nasm;

// 程序由一系列的语句组成
program : statement* EOF ;

// 语句可以是指令包、段声明、全局符号声明、变量定义、标号声明、指令尺寸定义、多数据定义、数据定义
statement : declare
          | instructionPacket
          ;

declare : Section Id
        | Global Id
        | Externed Id
        | Id idTail
        | Lbrace Bits num Rbrace
        | Times num size data
        | size data
        ;

idTail : Colon
       | Equ expr
       ;


data  : type ( Comma type )* ;

type   : sign? num
       | Id
       | Char
       ;

sign   : Add
       | Sub
       ;

instructionPacket : instruction ( Or instruction)* ;

instruction  : threeOp FuncUnit? operand Comma operand Comma operand
             | twoOp FuncUnit? operand Comma operand
             | oneOp FuncUnit? operand
             | noneOp FuncUnit?
             ;

threeOp : ADD
        | SUB
        ;

twoOp  : MV
       | MVK
       ;

oneOp  : NOP ;

noneOp : NOP ;

operand  : num
         | regs
         | memory
         ;

regs : reg ( Colon reg )? ;

reg : A0 | A1 | A2 | A3 | A4 | B0 | B1 | B2 | B3 | B4 ;

memory : Mul lop reg rop Lbrace ( reg | num ) Rbrace ;

lop : ( Increment | Add | Decrement | Sub )
    |
    ;

rop :  ( Increment | Decrement )
    |
    ;

expr : item ( adds item )* ;
adds : (Add | Sub) ;

item : factor ( muls factor)* ;
muls :  (Mul | Div) ;

factor : val ( shift val ) * ;
shift : ( Lshift | Rshift ) ;

val : Lparen expr Rparen
    | Id
    | num
    ;



num : Decimal
    | Octal
    | Hex
    | Binary
    ;

size   : Db
       | Dw
       | Dd
       | Dq
       ;

// 寄存器
A0 : A '0' ;
A1 : A '1' ;
A2 : A '2' ;
A3 : A '3' ;
A4 : A '4' ;
B0 : B '0' ;
B1 : B '1' ;
B2 : B '2' ;
B3 : B '3' ;
B4 : B '4' ;

// 数字
Decimal : [1-9][0-9]*
        | '0'
        ;

Octal : '0' [1-7][0-7]* ;

Hex :  '0' X [0-9a-fA-F]+ ;

Binary : '0' B [0-1]+ ;

WS : [ \t\r\n]+ -> skip ;

// 关键字

Vstart : V S T A R T ;

Global : G L O B A L ;

Externed : E X T E R N E D;

Section : S E C T I O N ;

Equ : E Q U ;

Times : T I M E S ;

Bits : B I T S ;

Db : D B ;
Dw : D W ;
Dd : D D ;
Dq : D Q ;

// 指令
ADD : A D D ;

SUB : S U B;

MVK : M V K ;

MV : M V ;

NOP : N O P ;

// 函数单元
FuncUnit : ( '.' S '1' | '.' S '2' | '.' L '1' | '.' L '2'    | '.' D '1'   | '.' D '2'  | '.' M '1' | '.' M '2' )  ;

// 标识符
Id : [a-zA-Z_.][a-zA-Z0-9_]* ;

// 字符
Char   : '\'' . '\'' ;

// 运算符
Add : '+' ;
Sub : '-' ;
Mul : '*' ;
Div : '\\' ;
Lshift : '<<' ;
Rshift : '>>' ;
Lbrace : '[' ;
Rbrace : ']' ;
Lparen : '(' ;
Rparen : ')' ;
Equal : '=' ;
Increment : '++' ;
Decrement : '--' ;
Or : '||' ;

// 标点符号
Colon : ':' ;
Comma : ',' ;
Semicolon : ';' ;

// 字符编码
A : ('A'|'a') ;
B : ('B'|'b') ;
C : ('C'|'c') ;
D : ('D'|'d') ;
E : ('E'|'e') ;
F : ('F'|'f') ;
G : ('G'|'g') ;
H : ('H'|'h') ;
I : ('I'|'i') ;
J : ('J'|'j') ;
K : ('K'|'k') ;
L : ('L'|'l') ;
M : ('M'|'m') ;
N : ('N'|'n') ;
O : ('O'|'o') ;
P : ('P'|'p') ;
Q : ('Q'|'q') ;
R : ('R'|'r') ;
S : ('S'|'s') ;
T : ('T'|'t') ;
U : ('U'|'u') ;
V : ('V'|'v') ;
W : ('W'|'w') ;
X : ('X'|'x') ;
Y : ('Y'|'y') ;
Z : ('Z'|'z') ;